/**
 * 代码中的类名、方法名、参数名已经指定，请勿修改，直接返回方法规定的值即可
 *
 * 
 * @param array int整型一维数组 
 * @return int整型一维数组
 */
 function FindNumsAppearOnce( array ) {
  // write code here
  // 第一步将数组当中所有的数组进行异或的计算
  var res = 0
  for(let i of array){
    res = res ^ i
  }
  // 假如说两个只出现了一次的数字是m,n的话 此时res当中存在的值 就是m和n异或的结果 因为出现两次的数字 经过他和他本身异或之后就变成了0 
  // 下面我们来查找m和n的异或结果也就是 res当中的最右边的1
  // 我们先初始化分解的数值是1 
  var div = 1
  while((div & res) === 0){ // 只要div和res相与 得到的结果是0 那就说明res 的这一位是0 那么我们就将这个分界的值左移一个单位 也就是从1 => 10 10=> 100 每次这个1都是向左移动一位
    // 这样当他跳出循环的时候 那么他的这个分解的数值就是 1 所在的位置就是mn异或的结果当中最右边的1
    div = div << 1
  }
  // 如果说mn那一位上异或的结果是1的话 那就说明m和n在这一位上面一个是0 一个是1 他异或的结果才会是1 
  // 所以说我们按照这个标准 将这个数组当中的数字 分到两个数组当中 其中的一个子数组 所有的数字在这一位上都是1 另外一组数组 所有数字 在这一位上的数字都是0 这样 mn就会被分到两个不同的子数组当中
  var m = 0
  var n = 0
  for(let i of array){
    if(i & div) { // 如果说这个数字和我们分界的数值 与 操作之后的数字是1 那就说明他在这一位上面是1 
      // 我们将这两个子数组当中的所有数字全部异或 和刚刚的道理一样 出现了两次的数字 就会全部抵消掉 那么最终两个子数组当中所有元素异或的结果就是m和n
      m = m ^ i
    }else{
      n = n ^ i 
    }
  }
  return [m,n].sort((a,b)=>{
    return a-b
  })
}
module.exports = {
  FindNumsAppearOnce : FindNumsAppearOnce
};